package cn.zhfeat.utils;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ListVersionsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.S3VersionSummary;
import com.amazonaws.services.s3.model.VersionListing;

/**
 * amazonaws s3 API
 * 
 * @author zhaoxin
 *
 */
public class FileUtil {
	private static Logger logger_FileUtil = LoggerFactory.getLogger(FileUtil.class);
	
	/**
	 * 现在参数先写死，后面考虑读配置文件
	 */
	private static String SERVICE_ENDPOINT_READ;	//公网
	private static String SERVICE_ENDPOINT_WRITE;	//公网
	private static String localhost_read;	//本地
	private static final String SIGNING_REGION = Regions.CN_NORTH_1.getName();
	private static String ACCESS_KEY;
	private static String SECRET_KEY;
	private static final Protocol PROTOCOL = Protocol.HTTP;
	private static String BUCKET_NAME;
	private static String visit_tenant;
	private static String visit_protocol;
	
	private static String backUplaodBaseUrl;
	
	private static AmazonS3 s3 = null;
	
	public static void main(String[] args) throws Exception {
		URL url = new URL("http://tvax4.sinaimg.cn/crop.0.0.180.180.180/006JvJBhly8fkk8m087d1j3050050dgk.jpg");
		InputStream openStream = url.openStream();
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setContentType("image/jpeg");
		String path = uploadFile(openStream, metadata,".jpg");
		System.out.println(path);	//http://oss.300.cn/cook_test:zhfeat-test/322c1976-2787-4e80-bc1c-0794decc4556.jpg
		//http://oss-img.300.cn/comm:bucket1/example.jpg?x-oss-process=image/resize,m_fixed,h_100,w_100
		//http://oss-img.300.cn/cook_test:zhfeat-test/322c1976-2787-4e80-bc1c-0794decc4556.jpg?x-oss-process=image/resize,m_fixed,h_100,w_100
//		String path = uploadFile("test_file.jpg", new File("C:\\Users\\zxdzy\\Desktop\\订餐报销填写.jpg"), null);
//		System.out.println(path);
		
//		InputStream downloadFile = downloadFile("test_file");
//		FileUtils.copyInputStreamToFile(downloadFile, new File("d:\\aa.java"));
	}
	
	static {
		try {
			Properties properties = new Properties();
			properties.load(FileUtil.class.getClassLoader().getResourceAsStream("conf/uploadFilePath.properties"));
			SERVICE_ENDPOINT_READ = properties.getProperty("SERVICE_ENDPOINT_READ");
			SERVICE_ENDPOINT_WRITE = properties.getProperty("SERVICE_ENDPOINT_WRITE");
			localhost_read = properties.getProperty("localhost_read");
			ACCESS_KEY = properties.getProperty("ACCESS_KEY");
			SECRET_KEY = properties.getProperty("SECRET_KEY");
			BUCKET_NAME = properties.getProperty("BUCKET_NAME");
			visit_tenant = properties.getProperty("visit_tenant");
			visit_protocol = properties.getProperty("visit_protocol");
			backUplaodBaseUrl = properties.getProperty("backUplaodBaseUrl");
			
			File dir = new File(backUplaodBaseUrl+"/"+BUCKET_NAME);
			if(!dir.exists()) {
				dir.mkdirs();
			}
			
			s3 = AmazonS3ClientBuilder.standard()
			.withEndpointConfiguration(new EndpointConfiguration(SERVICE_ENDPOINT_WRITE, SIGNING_REGION))
			.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY)))
			.withClientConfiguration(new ClientConfiguration().withProtocol(PROTOCOL))
			.withPathStyleAccessEnabled(true)
			.build();
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile----加载配置文件失败", e);
		}
	}

	public static String uploadFile(String bucketName, File file) {
		String result = null;
		String key = UUID.randomUUID().toString();
		try {
			String suffix = file.getName().substring(file.getName().lastIndexOf("."));
			key += suffix;
		}catch (Exception e) {
		}
		try {
			if(!s3.doesBucketExistV2(bucketName)) {
				s3.createBucket(bucketName);
			}
			s3.putObject(new PutObjectRequest(bucketName, key, file).withCannedAcl(CannedAccessControlList.PublicRead));
//			URL url = s3.getUrl(bucketName, key);
//			result = SERVICE_ENDPOINT_READ + url.getFile();
			result = visit_protocol+"://"+SERVICE_ENDPOINT_READ+"/"+visit_tenant+":"+bucketName+"/"+key;
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile", e);
		}
		return result;
	}
	public static String uploadFile(File file) {
		String result = null;
		String key = UUID.randomUUID().toString();
		try {
			String suffix = file.getName().substring(file.getName().lastIndexOf("."));
			key += suffix;
		}catch (Exception e) {
		}
		
		try {
			if(!s3.doesBucketExistV2(BUCKET_NAME)) {
				s3.createBucket(BUCKET_NAME);
			}
			s3.putObject(new PutObjectRequest(BUCKET_NAME, key, file).withCannedAcl(CannedAccessControlList.PublicRead));
//			URL url = s3.generatePresignedUrl(new GeneratePresignedUrlRequest(BUCKET_NAME, key).withExpiration(expiration));
			result = visit_protocol+"://"+SERVICE_ENDPOINT_READ+"/"+visit_tenant+":"+BUCKET_NAME+"/"+key;
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile", e);
			try {
				File destFile = new File(backUplaodBaseUrl+"/"+BUCKET_NAME+"/"+key);
				FileUtils.copyFile(file, destFile);
				result = localhost_read + destFile.getAbsolutePath();
			}catch (Exception e2) {
				logger_FileUtil.error("FileUtil.uploadFile----人品太次，本地存储都失败", e2);
			}
		}
		
		return result;
	}
	public static String uploadFile(String bucketName, InputStream is, ObjectMetadata metadata) {
		String result = null;
		String key = UUID.randomUUID().toString();
		try {
			if(!s3.doesBucketExistV2(bucketName)) {
				s3.createBucket(bucketName);
			}
			s3.putObject(new PutObjectRequest(bucketName, key, is, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
//			URL url = s3.generatePresignedUrl(new GeneratePresignedUrlRequest(BUCKET_NAME, key).withExpiration(expiration));
//			result = SERVICE_ENDPOINT_READ + url.getFile();
			result = visit_protocol+"://"+SERVICE_ENDPOINT_READ+"/"+visit_tenant+":"+bucketName+"/"+key;
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile", e);
		}
		return result;
	}
	public static String uploadFile(InputStream is, ObjectMetadata metadata) {
		String result = null;
		String key = UUID.randomUUID().toString();
		try {
			if(!s3.doesBucketExistV2(BUCKET_NAME)) {
				s3.createBucket(BUCKET_NAME);
			}
			s3.putObject(new PutObjectRequest(BUCKET_NAME, key, is, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
//			URL url = s3.generatePresignedUrl(new GeneratePresignedUrlRequest(BUCKET_NAME, key).withExpiration(expiration));
			result = visit_protocol+"://"+SERVICE_ENDPOINT_READ+"/"+visit_tenant+":"+BUCKET_NAME+"/"+key;
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile", e);
			try {
				File destFile = new File(backUplaodBaseUrl+"/"+BUCKET_NAME+"/"+key);
				FileUtils.copyInputStreamToFile(is, destFile);
				result = localhost_read + destFile.getAbsolutePath();
			}catch (Exception e2) {
				logger_FileUtil.error("FileUtil.uploadFile----人品太次，本地存储都失败", e2);
			}
		}
		return result;
	}
	/**
	 * 
	 * @param is
	 * @param metadata
	 * @param suffix	文件后缀，例如：.jpg  .xml  .mp3
	 * @return
	 */
	public static String uploadFile(InputStream is, ObjectMetadata metadata, String suffix) {
		String result = null;
		String key = UUID.randomUUID().toString() + suffix;
		try {
			if(!s3.doesBucketExistV2(BUCKET_NAME)) {
				s3.createBucket(BUCKET_NAME);
			}
			s3.putObject(new PutObjectRequest(BUCKET_NAME, key, is, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
			result = visit_protocol+"://"+SERVICE_ENDPOINT_READ+"/"+visit_tenant+":"+BUCKET_NAME+"/"+key;
		}catch (Exception e) {
			logger_FileUtil.error("FileUtil.uploadFile", e);
			try {
				File destFile = new File(backUplaodBaseUrl+"/"+BUCKET_NAME+"/"+key);
				FileUtils.copyInputStreamToFile(is, destFile);
				result = localhost_read + destFile.getAbsolutePath();
			}catch (Exception e2) {
				logger_FileUtil.error("FileUtil.uploadFile----人品太次，本地存储都失败", e2);
			}
		}
		return result;
	}
	
	public static void deleteFile(String bucketName, String key) {
		s3.deleteObject(bucketName, key);
	}
	public static void deleteFile(String key) {
		s3.deleteObject(BUCKET_NAME, key);
	}
	
	public static InputStream downloadFile(String bucketName, String key) {
		if(!s3.doesBucketExistV2(bucketName)) {
			return null;
		}
		S3Object o = s3.getObject(bucketName, key);
		InputStream is = o.getObjectContent();
		return is;
	}
	public static InputStream downloadFile(String key) {
		if(!s3.doesBucketExistV2(BUCKET_NAME)) {
			return null;
		}
		S3Object o = s3.getObject(BUCKET_NAME, key);
		InputStream is = o.getObjectContent();
		return is;
	}

	public static Bucket getBucket(String bucket_name) {
		Bucket named_bucket = null;
		List<Bucket> buckets = s3.listBuckets();
		for (Bucket b : buckets) {
			if (b.getName().equals(bucket_name)) {
				named_bucket = b;
				break;
			}
		}
		return named_bucket;
	}

	public static Bucket createBucket(String bucket_name) {
		Bucket b = null;
		if (s3.doesBucketExistV2(bucket_name)) {
			System.out.format("Bucket %s already exists.\n", bucket_name);
			b = getBucket(bucket_name);
		} else {
			try {
				b = s3.createBucket(bucket_name);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return b;
	}

	public static void deleteBucket(String bucket_name) {
		System.out.println("Deleting S3 bucket: " + bucket_name);
		final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();

		try {
			System.out.println(" - removing objects from bucket");
			ObjectListing object_listing = s3.listObjects(bucket_name);
			while (true) {
				for (Iterator<?> iterator = object_listing.getObjectSummaries().iterator(); iterator.hasNext();) {
					S3ObjectSummary summary = (S3ObjectSummary) iterator.next();
					s3.deleteObject(bucket_name, summary.getKey());
				}

				if (object_listing.isTruncated()) {
					object_listing = s3.listNextBatchOfObjects(object_listing);
				} else {
					break;
				}
			}

			System.out.println(" - removing versions from bucket");
			VersionListing version_listing = s3.listVersions(new ListVersionsRequest().withBucketName(bucket_name));
			while (true) {
				for (Iterator<?> iterator = version_listing.getVersionSummaries().iterator(); iterator.hasNext();) {
					S3VersionSummary vs = (S3VersionSummary) iterator.next();
					s3.deleteVersion(bucket_name, vs.getKey(), vs.getVersionId());
				}

				if (version_listing.isTruncated()) {
					version_listing = s3.listNextBatchOfVersions(version_listing);
				} else {
					break;
				}
			}

			System.out.println(" OK, bucket ready to delete!");
			s3.deleteBucket(bucket_name);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Done!");
	}
}